/*
 * Example_03.cpp
 *
 *  Tic-Tac-Toe
 */

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

class Board {
private:
	char _matrix[3][3];
	int _counter;
public:
	Board() : _counter(0) {
		init();
	}
	void init();
	friend ostream &operator<<( ostream &stream, Board board );
	bool isEmptyCell( unsigned row, unsigned col );
	void setUserCell( unsigned row, unsigned col, char ch );
	void setEmptyCell( char ch );
	inline bool isFull() { return _counter >= 9; }
	bool isWinner( char ch );
};

class Game {
private:
	Board _board;
public:
	void start();
	void play();
};

ostream &operator<<( ostream &stream, Board board ) {
	stream << "  1 2 3 " << endl;
	for( int i = 0; i < 3; i++ ) {
		stream << i + 1 << '|';
		for( int j = 0; j < 3; j++ )
			stream << board._matrix[i][j] << '|';
		stream << endl;
	}
	return stream;
}

void Board::init() {
	for( int i = 0; i < 3; i++ )
		for( int j = 0; j < 3; _matrix[i][j++] = '.' );
}
bool Board::isEmptyCell( unsigned row, unsigned col ) {
	if( row*col == 0 || row*col > 9 ) {
		cout << "Invalid cell" << endl;
		return false;
	}
	return _matrix[row-1][col-1] == '.';
}
void Board::setUserCell( unsigned row, unsigned col, char ch ) {
	if( isEmptyCell( row, col ) ) {
		_matrix[row-1][col-1] = ch;
		_counter++;
	}
}
void Board::setEmptyCell( char ch ) {
	for( int i = 0; i < 3; i++ ) {
		bool done = false;
		for( int j = 0; j < 3 && ! done ; j++ )
			if( _matrix[i][j] == '.' ) {
				_matrix[i][j] = ch;
				_counter++;
				done = true;
			}
		if( done )
			break;
	}
}
bool Board::isWinner( char ch ) {
	bool winner;
	// check rows
	for( int i = 0; i < 3; i++ ) {
		winner = true;
		for( int j = 0; j < 3 && winner; j++ )
			winner = _matrix[i][j] == ch;
		if( winner )
			break;
	}
	if( ! winner ) {
		// check cols
		for( int j = 0; j < 3; j++ ) {
			winner = true;
			for( int i = 0; i < 3 && winner; i++ )
				winner = _matrix[i][j] == ch;
			if( winner )
				break;
		}
	}
	if( ! winner ) {
		// check diags
		winner = true;
		for( int i = 0; i < 3 && winner; i++ )
			winner = _matrix[i][i] == ch;
		if( ! winner ) {
			winner = true;
			for( int j = 0; j < 3 && winner; j++ )
				winner = _matrix[2-j][j] == ch;
		}
	}
	return winner;
}

void Game::start() {
	_board.init();
	cout << "= Starting new game =" << endl;
}
void Game::play() {
	while( ! _board.isFull() ) {
		cout << _board;
		bool interrupted = false;
		while( true ) {
			cout << "Enter row col: ";
			string line;
			getline( cin, line );
			if( line.size() <= 1 ) {
				cout << "Game interrupted" << endl;
				interrupted = true;
				break;
			}
			unsigned row = 0, col = 0;
			sscanf( line.c_str(), "%d %d", &row, &col );
			if( _board.isEmptyCell( row, col ) ) {
				_board.setUserCell( row, col, 'X' );
				break;
			} else
				cout << "# Invalid row,col pair" << endl;
		}
		if( interrupted )
			break;
		if( _board.isWinner( 'X' ) ) {
			cout << "YOU are WINNER!" << endl;
			break;
		}
		if( ! _board.isFull() ) {
			_board.setEmptyCell( '0' );
			if( _board.isWinner( '0' ) ) {
				cout << "COMP is WINNER!" << endl;
				break;
			}
		}
	}
	cout << _board << "= Game finished =" << endl;
}

//int main() {
//	cout << "Example_03" << endl << "----------" << endl;
//	Game game;
//	game.start();
//	game.play();
//}
